package mts.gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import mts.ElevatorControllerInternalConnection;
import mts.ElevatorControllerInternalConnectionServer;
import mts.ElevatorControllerManager;
import mts.ElevatorControllerView;
import mts.ProjectControllerManager;
import mts.common.CommonSettings;
import mts.groupdispatcher.GroupDispatcher;
import mts.testframework.tests.FireEvacuationStressTest;
import mts.testframework.tests.MorningRushStressTest;

import org.apache.log4j.Logger;

public class MainGui extends JFrame implements ProjectControllerManager {

	private static final long serialVersionUID = 2143539525002077488L;
	private static final Logger log = Logger.getLogger(MainGui.class);
	
	Panel carGroup;
	private int elevatorControllerCount = 0;
	private GroupDispatcher groupDispatcher;
	private ElevatorControllerInternalConnectionServer internalConnectionServer;
	
	public void setInternalConnectionServer(ElevatorControllerInternalConnectionServer internalConnectionServer) {
		this.internalConnectionServer = internalConnectionServer;
	}

	public ElevatorControllerInternalConnectionServer getInternalConnectionServer() {
		return internalConnectionServer;
	}	
	
	
	@Override
	public GroupDispatcher getGroupDispatcher() {
		return groupDispatcher;
	}
	
	@Override
	public void setGroupDispatcher(GroupDispatcher groupDispatcher) {
		this.groupDispatcher = groupDispatcher;
		
	}		
	
	byte controllerCount = 0;
	//private List<CarPanel> carPanels = new ArrayList<CarPanel>(CommonSettings.MAX_ELEVATOR_CONTROLLERS);
	
	public MainGui() {
		super("SYSC 3303 - 'megamouse-transport-system' - connected to 0 Elevator Controllers");
		
				
		log.info("GUI is being initialized");
		
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		
		setSize(1024, 768);
		
		Container cp = getContentPane();
		
		this.setJMenuBar(createMenuBar());
		
		
		
		
		cp.setLayout(new BorderLayout(5, 5));
	
		
		Panel floorGroup = new Panel();
		
		floorGroup.setLayout(new GridLayout(CommonSettings.MAX_FLOORS, 1));
		
		FloorPanel topFloorPanel = new FloorPanel(this, (byte)(CommonSettings.NUMBER_OF_FLOORS - 1), FloorPanel.HAS_DOWN);
		floorGroup.add(topFloorPanel);
		for (int i = CommonSettings.NUMBER_OF_FLOORS - 2; i > 0; i--) {
			FloorPanel floorPanel = new FloorPanel(this, (byte)i);
			floorGroup.add(floorPanel);
		}
		FloorPanel bottomFloorPanel = new FloorPanel(this, (byte)0, FloorPanel.HAS_UP);
		floorGroup.add(bottomFloorPanel);
		
		cp.add(floorGroup, BorderLayout.WEST);
		
		
		
		carGroup = new Panel();
		carGroup.setLayout(new GridLayout(2, 4, 5, 5));
		
//		for (int i = 0; i < 8; i++) {
//			CarPanel carPanel = new CarPanel((byte)i);
//			carPanels.add(carPanel);
//			carGroup.add(carPanel);
//		}
		
		cp.add(carGroup);
		
		setVisible(true);
		log.info("GUI is fully initialized");
	}

	private JMenuBar createMenuBar() {
		JMenuBar menuBar = new JMenuBar();
		
		// file menu
		JMenu fileMenu = new JMenu("File");
		fileMenu.setMnemonic(KeyEvent.VK_F);
		menuBar.add(fileMenu);
		
		JMenuItem spawnElevatorControllerMenuItem = new JMenuItem("Spawn a new elevator conroller on localhost");
		
		spawnElevatorControllerMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg) {
				ElevatorControllerManager.startElevatorProcess(controllerCount++);
			}
		});
		fileMenu.add(spawnElevatorControllerMenuItem);
		
		JMenuItem killElevatorControllersMenuItem = new JMenuItem("Kill elevator controllers spawned by GUI");
		
		killElevatorControllersMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg) {
				ElevatorControllerManager.stopAllElevatorControllerProcesses();
			}
		});
		fileMenu.add(killElevatorControllersMenuItem);
		
		
		fileMenu.addSeparator();
		JMenuItem exitMenuItem = new JMenuItem("Exit");	
		exitMenuItem.setMnemonic(KeyEvent.VK_E);
		exitMenuItem.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				ElevatorControllerManager.stopAllElevatorControllerProcesses();
				System.exit(0);
				
			}
		});
		fileMenu.add(exitMenuItem);
		
		//----------------------
		
		// Stress test Menu
		JMenu stressMenu = new JMenu("Stress Tests");
		stressMenu.setMnemonic(KeyEvent.VK_S);
		menuBar.add(stressMenu);
		

		
		JMenuItem stressTestMorningRush2 = new JMenuItem("Morning Rush Test - In Appt. (2 elevator controllers)");
		stressTestMorningRush2.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				MorningRushStressTest test = new MorningRushStressTest();
				test.startTest(groupDispatcher, getInternalConnectionServer(), 2);
				
			}
		});		
		stressMenu.add(stressTestMorningRush2);	
		
		JMenuItem stressTestMorningRush3 = new JMenuItem("Morning Rush Test - In Appt. (3 elevator controllers)");
		stressTestMorningRush3.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				MorningRushStressTest test = new MorningRushStressTest();
				test.startTest(groupDispatcher, getInternalConnectionServer(), 3);
				
			}
		});		
		stressMenu.add(stressTestMorningRush3);	
		
		JMenuItem fireEvacuationTest2 = new JMenuItem("Fire Evacuation Stress Test (2 elevator controllers)");
		fireEvacuationTest2.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				FireEvacuationStressTest test = new FireEvacuationStressTest();
				test.startTest(groupDispatcher, getInternalConnectionServer(), 2);
				
			}
		});		
		stressMenu.add(fireEvacuationTest2);
		
		JMenuItem fireEvacuationTest4 = new JMenuItem("Fire Evacuation Stress Test (4 elevator controllers)");
		fireEvacuationTest4.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				FireEvacuationStressTest test = new FireEvacuationStressTest();
				test.startTest(groupDispatcher, getInternalConnectionServer(), 4);
				
			}
		});		
		stressMenu.add(fireEvacuationTest4);		
		
		// ----------------------		
		
		
		return menuBar;
	}
	
	@Override
	public ElevatorControllerView addView(ElevatorControllerInternalConnection elevatorControllerInternalConnection) {
		return addElevatorControllerPanel(elevatorControllerInternalConnection);
		
	}
	
	
	
	public CarPanel addElevatorControllerPanel( ElevatorControllerInternalConnection elevatorControllerInternalConnection) {
		
		CarPanel carPanel = new CarPanel(this, elevatorControllerInternalConnection);
		//carPanels.put((byte)i,  carPanel);
		carGroup.add(carPanel);		
		
		elevatorControllerCount++;
		setTitle("SYSC 3303 - 'megamouse-transport-system' - connected to " + elevatorControllerCount + " Elevator Controllers");
		return carPanel;
	}

	@Override
	public void removeView(ElevatorControllerView elevatorControllerView) {
		carGroup.remove((CarPanel)elevatorControllerView);
		
	}


}
